package com.sparkseries.common.log.utils;

import jakarta.servlet.http.HttpServletRequest;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.regex.Pattern;

/**
 * IP 工具类,提供从 HttpServletRequest 中获取客户端真实 IP 地址的功能
 */
public class RemoteAddressUtils {

    private static final Logger logger = LoggerFactory.getLogger(RemoteAddressUtils.class);
    // 用于验证 IP 地址的正则表达式
    private static final Pattern IP_PATTERN = Pattern.compile("^((25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\.){3}(25[0-5]|2[0-4]\\d|[01]?\\d\\d?)$");
    // 可能包含客户端 IP 地址的请求头列表
    private static final String[] IP_HEADERS = {
            "x-forwarded-for",
            "Proxy-Client-IP",
            "WL-Proxy-Client-IP",
            "HTTP_CLIENT_IP",
            "HTTP_X_FORWARDED_FOR"
    };

    /**
     * 从 HttpServletRequest 中获取客户端的真实 IP 地址。
     * 该方法会依次检查多个可能包含客户端 IP 地址的请求头，
     * 如果都未找到有效的 IP 地址，则使用 request.getRemoteAddr() 获取。
     *
     * @param request HttpServletRequest 对象
     * @return 客户端的真实 IP 地址，如果无法获取则返回 null
     */
    public static String getIpAddr(HttpServletRequest request) {
        String ip = null;
        try {
            for (String header : IP_HEADERS) {
                ip = request.getHeader(header);
                if (isValidIp(ip)) {
                    // 如果 IP 地址是多个以逗号分隔的 IP，取第一个
                    ip = ip.split(",")[0].trim();
                    break;
                }
            }
            if (!isValidIp(ip)) {
                ip = request.getRemoteAddr();
            }
        } catch (Exception e) {
            logger.error("Failed to get client IP address", e);
        }
        return ip;
    }

    /**
     * 验证给定的字符串是否为有效的 IP 地址。
     *
     * @param ip 要验证的字符串
     * @return 如果是有效的 IP 地址则返回 true，否则返回 false
     */
    private static boolean isValidIp(String ip) {
        return !StringUtils.isEmpty(ip) &&
                !"unknown".equalsIgnoreCase(ip) &&
                IP_PATTERN.matcher(ip).matches();
    }
}